 

import '@material/web/all.js';
import { infoUtil } from "./util/infoUtil";
import { file, fileInfoBaseDto, getFileDownloadUrl} from "ispace.core.main"
import { downloadFileDto } from './dto/downloadFileDto';

console.log("file download Page"); 
let fileHandler = {
    set(target: any, prop: string, value: any) {
    target[prop] = value;
  
    // step 2.1: init
    let item = document.getElementById(`file-${target.id}`)!;
    item.innerHTML = `<div class="data-item-content">
            <span>${target.name}</span>
            <span>${ infoUtil.formatFileSize(target.size)} </span>
  <span>${target.status == "downloading"?(
                        '<md-circular-progress  value="'+target.progress+'"></md-circular-progress>'
                    ): infoUtil.convertDownloadStatus(target.status)}</span>
                  <span><a href="${getFileDownloadUrl(target.id)}" target="_blank" rel="noopener noreferrer" download style="text-decoration: underline;color: #3f51b5" >手动下载</a></span>
                    </div>`;

    // step 2: 更新进度
    let progressElement = document.getElementById(`progress`)! as HTMLProgressElement; 
    progressElement.value = getProgress();

    return true;
  },
}

class Program {

      // 是否下载中
      private _isDownloading = false
      get isDownloading() {
          return this._isDownloading;
      }
      set isDownloading(value) {
          this._isDownloading = value;

          // step 2.2: 更新下载按钮
          let reTryButtonElement = document.getElementById("reTryButton")!;
          reTryButtonElement.style.display = value?"none":"inline-block";
          
          let downloadAllButtonElement = document.getElementById("downloadAll")!;
          downloadAllButtonElement.style.display = value?"none":"inline-block";

          if(getProgress() == 1){
              reTryButtonElement.style.display = "none";
          }
 
         // 整体进度状态
         let progressElement = document.getElementById("progress")!;
         progressElement.style.display = value?"block":"none";
      }

      // 状态
      private _isCompressing = false
      get isCompressing() {
          return this._isCompressing;
      }
      set isCompressing(value) {
          this._isCompressing = value;

          // step 2.3: 更新压缩按钮
          let compressButtonElement = document.getElementById("progress-indeterminate")!;
          compressButtonElement.style.display = value?"block":"none";
      }


      // 状态
      private _status = "waiting"
      get status() {
          return this._status;
      }
      set status(value) {
          this._status = value;

          // step 2.4: 更新状态
          let statusElement = document.getElementById("status")!;
          statusElement.innerHTML = infoUtil.convertGvStatus(value);
      }

          // 清单列表
          private _fileList:downloadFileDto[] = [];
          get fileList() {
               return this._fileList;
          }
          set fileList(value) {
               this._fileList = value; 

               // step 2.1: init
               let fileListElement = document.getElementById("fileList")!;
               let dataItems = fileListElement.getElementsByClassName("data-item");
               for (let index = 0; index < dataItems.length; index++) {
                   const element = dataItems[index];
                   fileListElement.removeChild(element);
               }

               // step 2.2： 渲染
               for(let i=0; i < this.fileList.length; i++){
                   let fileData = this.fileList[i];
                   let fileElement = document.createElement("md-list-item");
                   fileElement.id = `file-${fileData.id}`;
                   fileElement.classList.add("data-item");
                   fileElement.innerHTML = `<div class="data-item-content">
                           <span>${fileData.name}</span>
                           <span>${ infoUtil.formatFileSize(fileData.size)} </span>
                           <span>${infoUtil.convertDownloadStatus(fileData.status)}</span>
                           </div>`;
                   fileListElement.appendChild(fileElement); 
               }
 
               if(this._fileList.length>0){
                   fileListElement.style.display = "block"; 
                   fileListElement.parentElement!.style.display = "block"; 
               }
               else{
                   fileListElement.style.display = "none";
                   fileListElement.parentElement!.style.display = "none";
               }


          }
          addFile(fileData:downloadFileDto) {
               this.fileList.push(fileData); 

               // step init:
               let fileListElement = document.getElementById("fileList")! 
               if(this._fileList.length>0){
                   fileListElement.style.display = "block"; 
                   fileListElement.parentElement!.style.display = "block"; 
               }
               else{
                   fileListElement.style.display = "none";
                   fileListElement.parentElement!.style.display = "none";
               }

               // step 1：渲染
               let fileElement = document.createElement("md-list-item");
               fileElement.id = `file-${fileData.id}`;
               fileElement.classList.add("data-item");
               fileElement.innerHTML = `<div class="data-item-content">
                       <span>${fileData.name}</span>
                       <span>${ infoUtil.formatFileSize(fileData.size)} </span>
                       <span>${infoUtil.convertDownloadStatus(fileData.status)}</span>
                       </div>`;
               fileListElement.appendChild(fileElement);
          }

      // 入口
      async main(){  
        // step init:
        let params = new URLSearchParams(window.location.search);
        let path = params.get("path");  

        // step check
        if((path?.length??0) == 0)
        {
            infoUtil.displayErrorInfo("文件地址不可空！"); 
            return;
        }
 
        // step 1: 获取文件内容
        const fileInfo = await file.statf(path!).toPromise();
        if(fileInfo == null)
        {
            infoUtil.displayErrorInfo("文件不存在或不可访问！");
            return;
        }

        // step 2： core  
        // step 2.1: 展示文件内容
        await this.displayFileInfo(fileInfo!); 



        // step 3： 事件绑定
        document.getElementById("reTryButton")!.onclick = async () => {  
        try{
            // step check:
            if(this.isDownloading) {
                infoUtil.displayErrorInfo("正在下载，请稍后重试！");
                return;
            }
            this.isDownloading = true;
            this.status = "start";
            await this.downloadFile(fileInfo!);
             }
        catch(e:any){
            infoUtil.displayErrorInfo("下载文件失败！"+ e.message);
            this.status = "error";
        }
        finally{
            this.isDownloading = false;
            this.isCompressing = false;
        }
        };

        document.getElementById("downloadAll")!.onclick = async () => {

            for(let i=0; i<this.fileList.length; i++){
                let fileData = this.fileList[i];
                fileData.status = "waiting";
            }
            
            document.getElementById("reTryButton")!.click();
        }

        document.getElementById("startButton")!.onclick = async () => {
            document.getElementById("startButton")!.style.display = "none";
             document.getElementById("reTryButton")!.click();
        }

    }

    // 下载文件
    async downloadFile(fileInfo: fileInfoBaseDto) { 
        
          // step check: 文件信息
        if(fileInfo.size == undefined || fileInfo.size <= 0)
        {
            infoUtil.displayErrorInfo("文件大小为0，无法下载！");
            this.status = "error";
            return;
        }
        
        // step 1: 直接下载
        if(fileInfo.isDir == false && fileInfo.size <= 1024 * 1024 * 100) { // 小于等于1GB
            // 直接下载
            // step 1.1: 添加记录
           let fileData = this.fileList.find(item => item.id == fileInfo.path!);
            if(fileData == undefined) {
                fileData = new Proxy<downloadFileDto>({
                id: fileInfo.path!,
                name: fileInfo.name!,
                size: fileInfo.size,
                path: fileInfo.path!,
                progress: 0,
                status: "waiting", 
            },fileHandler)
                this.addFile(fileData); 
            }
            if(fileData.status == "success") {
                return;
            } 
            await infoUtil.downloadFileWithProgress(getFileDownloadUrl(fileInfo.path!) , fileInfo.name ?? "downloaded_file", 
            (progress, received, total) => {
                fileData.status = "downloading";
                this.status = "downloading";
                fileData.progress = progress;
            });
            this.status = "success";
            fileData.status = "success";
            return;
        }
        else {
            let paths: string[] = [];
            if(this.fileList.length <=0) { 
                this.status = "compressing";
            // 大于1GB，使用分卷压缩下载
            // step 1: 获取分卷下载链接
            this.isCompressing = true;
              paths = await file.compression({
                sourcePath: fileInfo.path!,
                sourceType: fileInfo.isDir ? "folder" : "file",
                isVolume: true,
            }).toPromise()??[];
            this.isCompressing = false;
            if(paths == null || paths.length == 0) {
                infoUtil.displayErrorInfo("文件下载失败！");
                this.status = "error";
                return;
            } 
        }
            // step 2: 遍历添加到清单中
            for(let path of paths) {

                // step 2.1: 获取文件信息
                const fileInfo = await file.statf(path).toPromise();
                if(fileInfo == null)
                {
                    infoUtil.displayErrorInfo("文件不存在或不可访问！");
                    return;
                }

                let paths = path.split('/');
                let name = paths[paths.length-1];
                let fileData = new Proxy<downloadFileDto>({
                    id: path,
                    name: name,
                    size: fileInfo.size??0,
                    path: path,
                    progress: 0,
                    status: "waiting", 
                },fileHandler)
                this.addFile(fileData); 
            }

            // step 2: 遍历分卷下载链接，下载每个分卷
            this.status = "downloading";
            for(let item of this.fileList) {  
                if(item.status == "success") {
                    continue;
                }
                await infoUtil.downloadFileWithProgress(getFileDownloadUrl(item.path) , item.name?? "downloaded_file",
                 (progress, received, total) => {
                    item.status = "downloading";
                    item.progress = progress;
                });
                item.status = "success";
            }

            this.status = "success";
            return;
        }
    }

    // 展示文件内容
    async displayFileInfo(fileInfo:fileInfoBaseDto){  
    }  

}

let p = new Program();
p.main(); 

function getProgress() {
    let total = 0;
    let index = 0;
    p.fileList.forEach(file => {
        total += file.size??0;
        index += (file.progress??0)*(file.size??0);
    });

    if(total == 0) {
        return 0;
    }

    return index/total;
}

